package com.zonski.jbots.desktop.editer;

import com.zonski.jbots.desktop.client.EntityRendererFactory;
import com.zonski.jbots.desktop.client.EntityRenderer;
import com.zonski.jbots.desktop.client.TileRenderer;
import com.zonski.jbots.desktop.client.tile.IndexedTileRenderer;
import com.zonski.jbots.desktop.client.entity.HashedEntityRendererFactory;
import com.zonski.jbots.desktop.client.entity.ImageEntityRenderer;
import com.zonski.jbots.desktop.client.entity.ChargerRenderer;
import com.zonski.jbots.desktop.editer.tool.CreateTool;
import com.zonski.jbots.desktop.editer.tool.TileTool;
import com.zonski.jbots.desktop.editer.tool.MoveTool;
import com.zonski.jbots.desktop.editer.tool.DeleteTool;
import com.zonski.jbots.engine.Modes;
import com.zonski.jbots.game.JBotsConstants;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.*;
import java.util.HashMap;
import java.util.ArrayList;

/**
 * Created by IntelliJ IDEA.
 * User: Chris Glover
 * Date: Oct 27, 2003
 * Time: 11:07:44 AM
 * To change this template use Options | File Templates.
 */
public class EditerActions
{
    private EditerOperations operations;

    private Action newAction;
    private Action openAction;
    private Action saveAction;
    private Action saveAsAction;
    private Action renameAction;
    private Action musicAction;

    private HashMap createActions;
    private HashMap toolActions;

    private ToolAction moveAction;
    private ToolAction deleteAction;

    private EntityRendererFactory rendererFactory;
    private TileRenderer tileRenderer;

    private ToolListener toggler = new ButtonUpdatingToolListener();

    public EditerActions(EditerOperations operations, EntityRendererFactory rendererFactory, TileRenderer tileRenderer)
    {
        this.operations = operations;
        this.createActions = new HashMap();
        this.toolActions = new HashMap();
        this.tileRenderer = tileRenderer;
        this.rendererFactory = rendererFactory;
    }

    public Action getNewAction()
    {
        if(this.newAction == null)
        {
            this.newAction = new AbstractAction()
            {
                public void actionPerformed(ActionEvent event)
                {
                    EditerActions.this.operations.newRoom();
                }
            };
            this.newAction.putValue(Action.NAME, "New");
        }
        return this.newAction;
    }

    public Action getSaveAction()
    {
        if(this.saveAction == null)
        {
            this.saveAction = new AbstractAction()
            {
                public void actionPerformed(ActionEvent event)
                {
                    EditerActions.this.operations.save();
                }
            };
            this.saveAction.putValue(Action.NAME, "Save");
        }
        return this.saveAction;
    }

    public Action getSaveAsAction()
    {
        if(this.saveAsAction == null)
        {
            this.saveAsAction = new AbstractAction()
            {
                public void actionPerformed(ActionEvent event)
                {
                    EditerActions.this.operations.saveAs();
                }
            };
            this.saveAsAction.putValue(Action.NAME, "Save As...");
        }
        return this.saveAsAction;
    }


    public Action getOpenAction()
    {
        if(this.openAction == null)
        {
            this.openAction = new AbstractAction()
            {
                public void actionPerformed(ActionEvent event)
                {
                    EditerActions.this.operations.open();
                }
            };
            this.openAction.putValue(Action.NAME, "Open...");
        }
        return this.openAction;
    }

    public Action getRenameAction()
    {
        if(this.renameAction == null)
        {
            this.renameAction = new AbstractAction()
            {
                public void actionPerformed(ActionEvent event)
                {
                    EditerActions.this.operations.rename();

                }
            };
            this.renameAction.putValue(Action.NAME, "Rename Room...");
        }
        return this.renameAction;
    }

    public Action getChangeMusicAction()
    {
        if(this.musicAction == null)
        {
            this.musicAction = new AbstractAction()
            {
                public void actionPerformed(ActionEvent event)
                {
                    EditerActions.this.operations.remusic();
                }
            };
            this.musicAction.putValue(Action.NAME, "Change Music...");
        }
        return this.musicAction;
    }

    public Action getMoveAction(AbstractButton button)
    {
        if(this.moveAction == null)
        {
            MoveTool moveTool = new MoveTool();
            this.moveAction = new ToolAction(moveTool);
            this.moveAction.putValue(Action.NAME, "Move Entity");
            this.toolActions.put(moveTool, this.moveAction);
            this.operations.getContext().getToolManager().addTool(moveTool);
            moveTool.addToolListener(this.toggler);
        }
        this.moveAction.buttons.add(button);
        return this.moveAction;
    }

    public Action getDeleteAction(AbstractButton button)
    {
        if(this.deleteAction == null)
        {
            DeleteTool deleteTool = new DeleteTool();
            this.deleteAction = new ToolAction(deleteTool);
            this.deleteAction.putValue(Action.NAME, "Delete Entity");
            this.toolActions.put(deleteTool, this.deleteAction);
            this.operations.getContext().getToolManager().addTool(deleteTool);
            deleteTool.addToolListener(this.toggler);
        }
        this.deleteAction.buttons.add(button);
        return this.deleteAction;
    }

    public Action getCreateAction(String toCreate, AbstractButton button)
    {
        ToolAction action = (ToolAction)this.createActions.get(toCreate);
        if(action == null)
        {
            int defaultLayer = getDefaultLayer(toCreate);
            CreateTool tool = new CreateTool(toCreate, defaultLayer);
            action = new ToolAction(tool);
            action.putValue(Action.NAME, toCreate);
            EntityRenderer renderer = ((HashedEntityRendererFactory)this.rendererFactory).getRenderer(toCreate);
            Image image;
            if(renderer instanceof ImageEntityRenderer)
            {
                image = ((ImageEntityRenderer)renderer).getImageFactory(Modes.NONE).getImage(0);
            }else if(renderer instanceof ChargerRenderer){
                image = ((ChargerRenderer)renderer).getActiveImage();
            }else{
                image = null;
            }
            if(image != null)
            {
                action.putValue(Action.SMALL_ICON, new ImageIcon(image));
            }
            this.operations.getContext().getToolManager().addTool(tool);
            this.createActions.put(toCreate, action);
            this.toolActions.put(tool, action);
            tool.addToolListener(this.toggler);
        }
        action.buttons.add(button);
        return action;
    }

    public Action getTileAction(int id, AbstractButton button)
    {
        Image image = ((IndexedTileRenderer)this.tileRenderer).getImage(id);
        ToolAction action;
        if(image != null)
        {
            TileTool tool = new TileTool(id);
            action = new ToolAction(tool);
            action.buttons.add(button);
            action.putValue(Action.SMALL_ICON, new ImageIcon(image));
            this.operations.getContext().getToolManager().addTool(tool);
            this.toolActions.put(tool, action);
            tool.addToolListener(this.toggler);
        }else{
            action = null;
        }
        return action;
    }

    private void activateWidgets(ToolAction action)
    {
        for(int i=0; i<action.buttons.size(); i++)
        {
            AbstractButton button = (AbstractButton)action.buttons.get(i);
            button.setSelected(true);
        }
    }

    private void deactivateWidgets(ToolAction action)
    {
        for(int i=0; i<action.buttons.size(); i++)
        {
            AbstractButton button = (AbstractButton)action.buttons.get(i);
            button.setSelected(false);
        }
    }

    private class ToolAction extends AbstractAction
    {
        private ArrayList buttons;
        private Tool tool;
        public ToolAction(Tool tool)
        {
            this.tool = tool;
            this.buttons = new ArrayList(3);
        }

        public void actionPerformed(ActionEvent event)
        {
            this.tool.activate();
        }
    }

    private class ButtonUpdatingToolListener implements ToolListener
    {
        public void toolActivated(ToolEvent event)
        {
            ToolAction action = (ToolAction)EditerActions.this.toolActions.get(event.getTool());
            activateWidgets(action);
        }

        public void toolDeactivated(ToolEvent event)
        {
            ToolAction action = (ToolAction)EditerActions.this.toolActions.get(event.getTool());
            deactivateWidgets(action);
        }

    }

    private int getDefaultLayer(String entityType)
    {
        int layerId = -1;
        if(entityType.endsWith(JBotsConstants.ROCK))
        {
            layerId = 0;
        }else if(entityType.equals(JBotsConstants.RECHARGE)){
            layerId = 5;
        }else if(!entityType.endsWith(JBotsConstants.BOT)){
            layerId = 100;
        }
        return layerId;
    }
}
